﻿//<TunynetCopyright>
//--------------------------------------------------------------
//<copyright>青岛拓宇网络科技有限公司 2005-2008</copyright>
//<version>V0.5</verion>
//<createdate>2008-4-21</createdate>
//<author>mazq</author>
//<email>mazq@tunynet.com</email>
//<log date="2008-4-21">创建</log>
//--------------------------------------------------------------
//</TunynetCopyright>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using ChinaCustoms.Framework.DeluxeWorks.Library.OGUPermission;
using ChinaCustoms.Qingdao.Workflow.Supports;
using ChinaCustoms.Qingdao.Workflow.Permissions;
using System.Configuration;
using Tunynet.QingdaoCustoms.Utils;

namespace ChinaCustoms.Qingdao.Workflow.Controls
{

    /// <summary>
    /// 工作流跟踪控件
    /// </summary>
    [ToolboxData("<{0}:WorkflowTracking runat=server />")]
    public class WorkflowTracking : TemplatedWebControl
    {
        /// <summary>
        /// 应用程序CodeName
        /// </summary>
        private static readonly string ApplicationCodeName = ConfigurationManager.AppSettings["ApplicationCodeName"];

        /// <summary>
        /// 登录URL
        /// </summary>
        private static readonly string LoginUrl = ConfigurationManager.AppSettings["LoginUrl"];

        protected override void OnInit(EventArgs e)
        {
            if (SkinName == null)
                ExternalSkinFileName = "Skin-WorkflowTracking.ascx";
            else
                ExternalSkinFileName = SkinName;

            base.OnInit(e);
        }

        TreeView workflowTreeView;
        protected override void AttachChildControls()
        {
            workflowTreeView = FindControl("WorkflowTreeView") as TreeView;
        }

        protected override void OnLoad(EventArgs e)
        {
            //如果用户没有登录，则转向登录页面
            if (!Context.Request.IsAuthenticated)
            {
                Context.Response.Redirect(LoginUrl);
            }

            base.OnLoad(e);
            EnsureChildControls();

            if (!Page.IsPostBack)
            {
                if (!string.IsNullOrEmpty(this.Context.Request.QueryString["TaskGuid"]))
                {
                    try
                    {
                        this.taskGUID = new Guid(this.Context.Request.QueryString["TaskGuid"]);
                    }
                    catch
                    {
                        this.taskGUID = Guid.Empty;
                    }
                }

                if (TaskGUID == Guid.Empty)
                {
                    this.Visible = false;
                    return;
                }

                TaskInfo task = Tasks.GetTask(TaskGUID);
                WorkflowInstanceInfo workflowInstanceInfo = WorkflowInstances.GetWorkflow(task.WorkflowGuid);

                string endActivityCodeName = string.Empty;


                string headerText = string.Format("<table cellpadding=\"5\" cellspacing=\"0\" style=\"border-width:0;width:{0}px\"><tr><td style=\"width:15%;vertical-align:middle\">{1}</td><td style=\"width:15%;vertical-align:middle\">{2}</td><td style=\"width:auto\">{3}</td><td style=\"width:15%;vertical-align:middle\">{4}</td><td style=\"width:15%;vertical-align:middle\">{5}</td></tr></table>", this.Width, "操作环节", "操作人", "流转到", "接收时间", "办理时间");
                headerText = "<b>" + headerText + "</b>";
                TreeNode headerNode = new TreeNode(headerText, string.Empty);
                headerNode.SelectAction = TreeNodeSelectAction.None;
                workflowTreeView.Nodes.Add(headerNode);

                List<ActivityInstanceInfo> activities = ActivityInstances.GetActivities(task.WorkflowGuid, null);
                this.ConstructTree(this.workflowTreeView.Nodes, Guid.Empty, activities);

                if (task.Status == TaskStatus.Completed)
                {
                    WorkItemInfo lastWorkItem = WorkItems.GetWorkItem(task.LastWorkItemGuid);
                    //处理办结
                    PopulateFinishedWorkItem(workflowTreeView.Nodes, lastWorkItem);
                }

            }

        }


        private void ConstructTree(TreeNodeCollection tnc, Guid? subFlowTaskGuid, List<ActivityInstanceInfo> activities)
        {
            for (int i = 0; i < activities.Count; i++)
            {
                ActivityInstanceInfo activity = activities[i];
                if (activity.SubTaskGuid == subFlowTaskGuid)
                {
                    TreeNode tempNode = null;
                    string subTaskOrganizationName = string.Empty;

                    if (activity.IsSubFlow == true)
                    {
                        string activityNameDisplay = activity.ActivityName;
                        if (string.IsNullOrEmpty(subTaskOrganizationName) == false)
                        {
                            activityNameDisplay += string.Format("[{0}]", subTaskOrganizationName);
                        }

                        //获取本子流程活动的所以完成的工作项
                        List<WorkItemInfo> workItemList = WorkItems.GetAllWorkItemOfActivity(activity.ActivityGuid, WorkItemStatus.Completed);
                        if (workItemList == null)
                        {
                            workItemList = new List<WorkItemInfo>();
                        }

                        tempNode = ConstructTreeNode(activityNameDisplay, "", "", "", "", activity.ActivityGuid.ToString());
                        tnc.Add(tempNode);

                        List<SubTaskInfo> subTaskList = SubTasks.GetSubTasks(activity.ActivityGuid, null);
                        for (int j = 0; j < subTaskList.Count; j++)
                        {
                            for (int k = workItemList.Count - 1; k >= 0; k--)
                            {
                                if (workItemList[k].CreateDate < subTaskList[j].CreateDate)
                                {
                                    //tempNode.ChildNodes.Add(ConstructTreeNode(workItemList[k].ActivityName,workItemList[k].ExecutorDisplayName,workItemList[k].CreatorUserName,workItemList[k].CreateDate.ToString(),workItemList[k].LastUpdateDate.ToString(),workItemList[k].WorkItemGuid.ToString()));
                                    PopulateNextWorkItems(tempNode.ChildNodes, workItemList[k], true);
                                    workItemList.RemoveAt(k);
                                }
                            }

                            string subTaskNumberToChild = (j + 1).ToString();
                            this.ConstructTree(tempNode.ChildNodes, subTaskList[j].SubTaskGuid, activities);

                            tempNode.ChildNodes.Add(new TreeNode(string.Empty));
                        }

                        for (int k = 0; k < workItemList.Count; k++)
                        {
                            //tempNode.ChildNodes.Add(ConstructTreeNode( workItemList[k].ActivityName, workItemList[k].ExecutorDisplayName, workItemList[k].CreatorUserName, workItemList[k].CreateDate.ToString(), workItemList[k].LastUpdateDate.ToString(), workItemList[k].WorkItemGuid.ToString()));
                            PopulateNextWorkItems(tempNode.ChildNodes, workItemList[k], true);
                        }
                    }
                    else
                    {
                        List<WorkItemInfo> workItemList = WorkItems.GetAllWorkItemOfActivity(activity.ActivityGuid, WorkItemStatus.Completed);
                        if (workItemList != null)
                        {
                            for (int j = 0; j < workItemList.Count; j++)
                            {
                                PopulateNextWorkItems(tnc, workItemList[j], i > 0 ? false : true);
                            }
                        }
                    }
                }
            }
        }


        /// <summary>
        /// 添加工作项流转情况节点
        /// </summary>
        /// <param name="nodeCollection"></param>
        /// <param name="workItem"></param>
        /// <param name="isFirstWorkItem">是否为活动的第一个工作项</param>
        void PopulateNextWorkItems(TreeNodeCollection nodeCollection, WorkItemInfo workItem, bool isFirstWorkItem)
        {
            List<WorkItemInfo> nextWorkItems = WorkItems.GetNextWorkItems(workItem.WorkItemGuid);
            if (nextWorkItems != null && nextWorkItems.Count > 0)
            {
                for (int i = 0; i < nextWorkItems.Count; i++)
                {
                    TreeNode workItemTreeNode = new TreeNode();
                    workItemTreeNode.SelectAction = TreeNodeSelectAction.Expand;

                    string displayActivityName = string.Empty;
                    string displayExcutorName = string.Empty;
                    string displayReceiverName = string.Empty;
                    string displayReceiverTime = string.Empty;
                    string displayDealWithTime = string.Empty;

                    //处理 操作环节、操作人
                    if (i == 0) //第一个后续工作项
                    {
                        displayActivityName = workItem.ActivityName;
                        displayExcutorName = workItem.ExecutorDisplayName;
                    }
                    else
                    {
                        displayActivityName = string.Empty;
                        displayExcutorName = string.Empty;
                    }

                    //处理 流转到
                    displayReceiverName = "[" + nextWorkItems[i].ActivityName + "]" + nextWorkItems[i].ExecutorDisplayName + "(" + PermissionUtils.StripDisplayNameFromUserFullPath(nextWorkItems[i].ExecutorFullPath) + ")";

                    //处理 接收时间
                    if (isFirstWorkItem || i > 0)
                    {
                        displayReceiverTime = string.Empty;
                    }
                    else
                    {
                        displayReceiverTime = nextWorkItems[i].CreateDate.ToString();
                    }

                    if (nextWorkItems[i].Status == WorkItemStatus.Completed)
                    {
                        displayDealWithTime = nextWorkItems[i].LastUpdateDate.ToString();
                    }

                    string nodeDisplayText = string.Format("<table cellpadding=\"5\" cellspacing=\"0\" style=\"border-width:0;width:{0}px\"><tr><td style=\"width:15%;vertical-align:middle\">{1}</td><td style=\"width:15%;vertical-align:middle\">{2}</td><td style=\"width:auto\">{3}</td><td style=\"width:15%;vertical-align:middle\">{4}</td><td style=\"width:15%;vertical-align:middle\">{5}</td></tr></table>",
                        this.Width, displayActivityName, displayExcutorName, displayReceiverName, displayReceiverTime, displayDealWithTime);
                    workItemTreeNode.Text = nodeDisplayText;
                    workItemTreeNode.Value = nextWorkItems[i].WorkItemGuid.ToString();

                    nodeCollection.Add(workItemTreeNode);
                }
            }

        }

        private TreeNode ConstructTreeNode(string displayActivityName, string displayExcutorName, string displayReceiverName, string displayReceiverTime, string displayDealWithTime, string nodeValue)
        {
            TreeNode workItemTreeNode = new TreeNode();
            workItemTreeNode.SelectAction = TreeNodeSelectAction.Expand;

            string nodeDisplayText = string.Format("<table cellpadding=\"5\" cellspacing=\"0\" style=\"border-width:0;width:{0}px\"><tr><td style=\"width:15%;vertical-align:middle\">{1}</td><td style=\"width:15%;vertical-align:middle\">{2}</td><td style=\"width:auto\">{3}</td><td style=\"width:15%;vertical-align:middle\">{4}</td><td style=\"width:15%;vertical-align:middle\">{5}</td></tr></table>",
                        this.Width, displayActivityName, displayExcutorName, displayReceiverName, displayReceiverTime, displayDealWithTime);
            workItemTreeNode.Text = nodeDisplayText;
            workItemTreeNode.Value = nodeValue;

            return workItemTreeNode;
        }

        /// <summary>
        /// 添加“办结”节点
        /// </summary>
        void PopulateFinishedWorkItem(TreeNodeCollection nodeCollection, WorkItemInfo workItem)
        {
            string displayActivityName = workItem.ActivityName;
            string displayExcutorName = workItem.ExecutorDisplayName;
            string displayReceiverName = "办结";
            string displayReceiverTime = workItem.CreateDate.ToString();

            string displayDealWithTime = string.Empty;
            if (workItem.Status == WorkItemStatus.Completed)
            {
                displayDealWithTime = workItem.LastUpdateDate.ToString();
            }

            TreeNode workItemTreeNode = new TreeNode();

            string nodeDisplayText = string.Format("<table cellpadding=\"5\" cellspacing=\"0\" style=\"border-width:0;width:{0}px\"><tr><td style=\"width:15%;vertical-align:middle\">{1}</td><td style=\"width:15%;vertical-align:middle\">{2}</td><td style=\"width:auto\">{3}</td><td style=\"width:15%;vertical-align:middle\">{4}</td><td style=\"width:15%;vertical-align:middle\">{5}</td></tr></table>",
                       this.Width, displayActivityName, displayExcutorName, displayReceiverName, displayReceiverTime, displayDealWithTime);

            workItemTreeNode.Text = nodeDisplayText;
            workItemTreeNode.Value = workItem.WorkItemGuid.ToString();
            workItemTreeNode.SelectAction = TreeNodeSelectAction.None;

            nodeCollection.Add(workItemTreeNode);
        }


        /// <summary>
        /// 生成活动节点
        /// </summary>
        /// <param name="activity">活动</param>
        TreeNode PopulateTreeNodeFromActivity(ActivityInstanceInfo activity)
        {
            TreeNode activityTreeNode = new TreeNode(activity.ActivityName, activity.ActivityGuid.ToString());
            return activityTreeNode;
        }


        #region 属性

        private Guid taskGUID = Guid.Empty;

        /// <summary>
        /// 任务ID
        /// </summary>
        public Guid TaskGUID
        {
            get { return taskGUID; }
            set { taskGUID = value; }
        }

        private int width = 1000;
        /// <summary>
        /// 宽度
        /// </summary>
        public new int Width
        {
            get { return width; }
            set { width = value; }
        }
        #endregion

    }
}
